﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Suucha.Expressions
{
    /// <summary>
    /// Suucha Expression Json 转换器，这是反序列化时使用
    /// </summary>
    public class ExpressionJsonConverter : JsonConverter
    {
        /// <summary>
        /// 判断是否可以转换
        /// </summary>
        /// <param name="objectType">需要转换的类型</param>
        /// <returns></returns>
        public override bool CanConvert(Type objectType)
        {
            return typeof(SuuchaExpression).IsAssignableFrom(objectType);
        }
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="reader">JsonReader</param>
        /// <param name="objectType">目标类型</param>
        /// <param name="existingValue">已经存在的值</param>
        /// <param name="serializer">JsonSerializer</param>
        /// <returns>返回反序列化的对象</returns>
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                return null;
            }
            JObject jo = JObject.Load(reader);            
            return FromJObject(jo);
        }

        private  SuuchaExpression FromJObject(JObject jobject)
        {
            var nodeToken = jobject["NodeType"];
            if (nodeToken == null)
                throw new InvalidOperationException(Resources.Resource("无效的Json"));
            SuuchaExpressionType nodeType = (SuuchaExpressionType)(Convert.ToInt32(((JValue)nodeToken).Value));
            switch (nodeType)
            {
                case SuuchaExpressionType.Constant:
                    var constantToken = jobject["Value"];
                    if (constantToken == null)
                    {
                        throw new InvalidOperationException(Resources.Resource("无效的Json"));
                    }
                    object value = ((JValue)constantToken).Value;
                    return SuuchaExpression.Constant(value);
                case SuuchaExpressionType.Member:
                    var nameToken = jobject["Name"];
                    if (nameToken == null)
                    {
                        throw new InvalidOperationException(Resources.Resource("无效的Json"));
                    }
                    string name = Convert.ToString(((JValue)nameToken).Value);
                    return SuuchaExpression.Member(name);

            }
            var leftJObject = jobject["Left"] as JObject;
            var rightJObject = jobject["Right"] as JObject;
            if (leftJObject == null || rightJObject == null)
            {
                throw new InvalidOperationException(Resources.Resource("无效的Json"));
            }
            SuuchaExpression left = FromJObject(leftJObject);
            SuuchaExpression right = FromJObject(rightJObject);
            SuuchaBinaryExpression exp = new SuuchaBinaryExpression() { NodeType = nodeType, Left = left, Right = right };
            return exp;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="value"></param>
        /// <param name="serializer"></param>
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// 是否支持序列化
        /// </summary>
        public override bool CanWrite
        {
            get
            {
                
                return false;
            }
        }
    }
}
